﻿/**
 * 4500*3000  每格10像素
 */
module SnakeModule {
    /**
     * 出生时只有8个方向
     */
    var StartDirection: number[] = Array.apply(null, Array(8)).map((v, i) => i * (2 * Math.PI / 8));
    export class Snake {
        /**速度*/
        speed: number = 1;
        /**长度米*/
        length: number;
        /**方向，角度值*/
        direction: number;
        /**半径*/
        r: number;
        /**颜色*/
        color: string;
        /**当前头的位置*/
        head: Point;
        /**身子的位置数组,起始是4段*/
        body: Point[];
        /**每一点的目标位置*/
        bodyTarget: number[] = [];
        /**头每次变向时的点，身子第一个节点必须走这个路径*/
        headTarget: Point[] = [];

        constructor(public name: string) {
            this.length = 40;
            this.color = ranColor();
            this.r = 5;
            this.direction = StartDirection[ran(8)];
            this.head = { x: ran(3500) + 500, y: ran(2000) + 500 } //起始的头不最边上的500个像素内。防止出来就碰到头
            //this.head = { x: 500, y: 300 } //起始的头不最边上的500个像素内。防止出来就碰到头
            this.headTarget.push(clonePoint(this.head));
            this.body = Array.apply(null, Array(this.length / 10)).map((v, i) => {
                return {
                    x: this.head.x - this.r * 2 * (i + 1) * Math.cos(this.direction),
                    y: this.head.y + this.r * 2 * (i + 1) * Math.sin(this.direction)
                }
            });
            this.body.forEach((p, i) => {
                this.bodyTarget.push(0);
            });
        }
        //在当前的方向上移动一下
        public move() {
            this.head = {
                x: this.head.x + Math.cos(this.direction) * this.speed,
                y: this.head.y - Math.sin(this.direction) * this.speed
            }
            this.headTarget.push(clonePoint(this.head));
            this.body.forEach((p, i) => {
                var tarPoint = this.headTarget[this.bodyTarget[i]];
                var runPoint = run2Point(p, tarPoint, this.speed);
                p.x = runPoint.x;
                p.y = runPoint.y;
                //如果已经跑到了
                if (distance(p, tarPoint) < this.speed-0.1) {
                    this.bodyTarget[i]++;
                }
            });
            //简单清理一下headTarget
            if (this.headTarget.length > 1000) {
                //保留最后一个节点的尾巴，以方便在加身长时，能获取相应的目标
                let endIndex = this.bodyTarget.slice(-1)[0]-Math.floor(2*this.r/this.speed+1);
                this.bodyTarget = this.bodyTarget.map((n) => n -= endIndex);
                this.headTarget.splice(0, endIndex);
            }
            return this;
        }
        public runToPoint(pt: Point) {
            var p1 = this.head, p2 = pt;
            //本来应该是正值，(p2.y - p1.y）是反着的，所以加个-1
            if (p2.x > p1.x)
                this.direction = -1 * Math.asin((p2.y - p1.y) / distance(p1, p2));
            else
                this.direction = Math.PI - (-1) * Math.asin((p2.y - p1.y) / distance(p1, p2));
            return this;
        }
        //修改颜色
        public changeColor() {
            this.color = ranColor();
        }

        //加5分
        public addLength(l:number) {
            this.length += l;
            if (this.body.length <Math.floor( this.length / 10)) {
                var lastIndex=this.bodyTarget.slice(-1)[0] - Math.floor(2*this.r / this.speed )
                this.body.push(this.headTarget[lastIndex]);
                this.bodyTarget.push(lastIndex);
            }
        }
    }
}